﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using KTool2.Core;
using KTool2.Utility;

namespace KTool2.Impl
{
    class KanjiWordList : IKanjiWordList
    {
        private List<KanjiWord> highList;
        private List<KanjiWord> mediumList;
        private List<KanjiWord> lowList;
        private List<KanjiWord> randList;
        private double lowPercent;
        private double mediumPercent;
        private double highPercent;
        private int randNum;
        private int position;
        //private List<object> randomList = new List<object>();

        //public List<object> RandmList
        //{
        //    get { return randomList; }
        //}

        public KanjiWordList()
        {
            this.highList = new List<KanjiWord>();
            this.mediumList = new List<KanjiWord>();
            this.lowList = new List<KanjiWord>();
        }

        public void Add(KanjiWord kWord)
        {
            switch (kWord.MemRate)
            {
                case 1:
                case 2:
                    this.lowList.Add(kWord);
                    break;
                case 3:
                case 4:
                    this.mediumList.Add(kWord);
                    break;
                case 5:
                    this.highList.Add(kWord);
                    break;
            }

            lowPercent = (double)this.lowList.Count / this.Count;
            mediumPercent = (double)this.mediumList.Count / this.Count;
            highPercent = (double)this.highList.Count / this.Count;
        }

        public List<KanjiWord> HighList
        {
            get { return this.highList; }
        }

        public List<KanjiWord> MediumList
        {
            get { return this.mediumList; }
        }

        public List<KanjiWord> LowList
        {
            get { return this.lowList; }
        }

        public int Count
        {
            get { return this.highList.Count + this.mediumList.Count + this.lowList.Count; }
        }

        public KanjiWord RanDomKanji
        {
            get
            {
                randList = null;
                randNum = RandomGenerator.NextInt(1, 101);
                //this.randomList.Add(randNum);

                if (randNum > (100 - highPercent * 100) && this.highList.Count > 0)
                {
                    randList = this.highList;
                }
                else if (randNum > (100 - highPercent * 100 - mediumPercent * 100) && randNum <= (100 - highPercent) && this.mediumList.Count > 0)
                {
                    randList = this.mediumList;
                }
                else
                {
                    randList = this.lowList;
                }

                randNum = RandomGenerator.NextInt(0, randList.Count);
                //this.randomList.Add(randNum);
                //this.randomList.Add(randList[randNum]);

                return randList[randNum];
            }
        }

        public KanjiWord FairRanDomKanji
        {
            get
            {
                randList = null;
                randNum = RandomGenerator.NextInt(1, this.highList.Count + this.mediumList.Count + this.lowList.Count);
                //this.randomList.Add(randNum);

                if (randNum <= this.lowList.Count)
                {
                    return this.lowList[randNum - 1];
                }
                else if (randNum <= this.lowList.Count + this.mediumList.Count)
                {
                    return this.mediumList[randNum - this.lowList.Count - 1];
                }
                else
                {
                    return this.highList[randNum - this.lowList.Count - this.mediumList.Count - 1];
                }
                //randNum = RandomGenerator.NextInt(0, randList.Count);
                ////this.randomList.Add(randNum);
                ////this.randomList.Add(randList[randNum]);

                //return randList[randNum];
            }
        }

        //public IKanjiWord Current
        //{
        //    get
        //    {
        //        if (this.position < this.lowList.Count)
        //        {
        //            return this.lowList[position];
        //        }
        //        else if (this.position < this.lowList.Count + this.mediumList.Count)
        //        {
        //            return this.mediumList[position - this.lowList.Count];
        //        }
        //        else
        //        {
        //            return this.highList[position - this.lowList.Count - this.highList.Count];
        //        }
        //    }
        //}

        //public void Dispose()
        //{
        //    position = 0;
        //}

        //object System.Collections.IEnumerator.Current
        //{
        //    get { return Current; }
        //}

        //public bool MoveNext()
        //{
        //    ++this.position;
        //    return this.position < this.lowList.Count + this.mediumList.Count + this.highList.Count;
        //}

        //public void Reset()
        //{
        //    this.position = 0;
        //}


        //object IKanjiWordList.Current
        //{
        //    get { throw new NotImplementedException(); }
        //}

        //public IEnumerator<IKanjiWord> GetEnumerator()
        //{
        //    throw new NotImplementedException();
        //}

        //System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        //{
        //    throw new NotImplementedException();
        //}

        public KanjiWord ElementAt(int i)
        {
            if (i < this.lowList.Count)
            {
                return this.lowList[i];
            }
            else if (i < this.lowList.Count + this.mediumList.Count)
            {
                return this.mediumList[i - this.lowList.Count];
            }
            else
            {
                return this.highList[i - this.lowList.Count - this.highList.Count];
            }
        }

        //object IKanjiWordList.Current
        //{
        //    get
        //    {
        //        if (this.position < this.lowList.Count)
        //        {
        //            return this.lowList[position];
        //        }
        //        else if (this.position < this.lowList.Count + this.mediumList.Count)
        //        {
        //            return this.mediumList[position - this.lowList.Count];
        //        }
        //        else
        //        {
        //            return this.highList[position - this.lowList.Count - this.highList.Count];
        //        }
        //    }
        //}

        //public bool MoveNext()
        //{
        //    ++this.position;
        //    return this.position < this.lowList.Count + this.mediumList.Count + this.highList.Count;
        //}

        //public void Reset()
        //{
        //    this.position = 0;
        //}

        //public IEnumerator<IKanjiWord> GetEnumerator()
        //{
        //    throw new NotImplementedException();
        //}

        //System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        //{
        //    throw new NotImplementedException();
        //}

        public void Shuffle()
        {
            this.ShuffleSubList(ref highList);
            this.ShuffleSubList(ref mediumList);
            this.ShuffleSubList(ref lowList);
        }

        private void ShuffleSubList(ref List<KanjiWord> kanjiList)
        {
            int length = kanjiList.Count;
            int randPos;
            KanjiWord temp;

            while (length > 1)
            {
                randPos = RandomGenerator.NextInt(0, length--);
                temp = kanjiList[length].Clone() as KanjiWord;
                kanjiList[length] = kanjiList[randPos];
                kanjiList[randPos] = temp;
            }
        }

        public void SetMemrate(KanjiWord kWord, int newMemrate)
        {
            switch (kWord.MemRate)
            { 
                case 1:
                case 2:
                    this.lowList.Remove(kWord);
                    break;
                case 3:
                case 4:
                    this.mediumList.Remove(kWord);
                    break;
                case 5:
                    this.highList.Remove(kWord);
                    break;
            }

            kWord.MemRate = newMemrate;

            this.Add(kWord);
        }
    }
}
